package com.sg.common.util;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * @author daixulin
 * @version : v1.0
 */
public final class DateTimeUtil {

    DateTimeUtil() {

    }

    public static Long getSecond(String type, Long num) {
        if (type.equals("YEAR")) {
            return num * 31536000L;
        } else if (type.equals("MONTH")) {
            return num * 2592000L;
        } else if (type.equals("DAY")) {
            return num * 86400L;
        } else if (type.equals("HOUR")) {
            return num * 3600L;
        } else if (type.equals("MINUTES")) {
            return num * 60L;
        } else if (type.equals("SECOND")) {
            return num;
        }
        return 0L;
    }

    public static Date getCurrentMaxDateTime(Date date) {
        if (Objects.isNull(date)) {
            return null;
        }

        ZoneId zone = ZoneId.systemDefault();
        Instant instant = date.toInstant();
        LocalDateTime updateEndTimeMax = LocalDateTime.ofInstant(instant, zone).with(LocalTime.MAX);
        return Date.from(updateEndTimeMax.atZone(zone).toInstant());
    }

    /**
     * 获取某个日期的开始时间
     */
    public static Date getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Date(calendar.getTimeInMillis());
    }


    /**
     * 获取某个日期的结束时间
     */
    public static Date getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Date(calendar.getTimeInMillis() + 1000);
    }

    /**
     * 获取某个日期的结束时间
     */
    public static Date getDayEndTimeNoPlusOneSec(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Date(calendar.getTimeInMillis());
    }

    /**
     * 获取某个日期的结束时间
     */
    public static Date getDayEndTime99(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Date(calendar.getTimeInMillis());
    }

    public static Date calcTime(Date startDate, Integer minute) {
        Date retDate = new Date();
        try {
            long time = (startDate.getTime() / 1000) + minute * 60;
            retDate.setTime(time * 1000);
        } catch (Exception e) {
            return null;
        }
        return retDate;
    }

    public static String dateFormat(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatter.format(date);
    }

    public static String dateFormat2(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        return formatter.format(date);
    }

    /**
     * 获取年份
     */
    public static int getYear(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(Calendar.YEAR);
    }


    /**
     * 两个日期相减得到的天数
     */
    public static long getDiffDays(Date beginDate, Date endDate) {
        if (beginDate == null || endDate == null) {
            throw new IllegalArgumentException("getDiffDays param is null!");
        }
        return (endDate.getTime() - beginDate.getTime()) / (1000 * 60 * 60 * 24);
    }

    /**
     * 两个日期相减得到的月数
     */
    public static long getDiffMonth(Date beginDate, Date endDate) {
        LocalDate afterDate = LocalDate.of(getYear(beginDate), getMonth(beginDate), (int) getDayOfMounth(beginDate) + 1);
        LocalDate beforeDate = LocalDate.of(getYear(endDate), getMonth(endDate), (int) getDayOfMounth(endDate) + 1);
        return ChronoUnit.MONTHS.between(afterDate, beforeDate);
    }

    /**
     * 两个日期相减得到的年数
     */
    public static long getDiffYear(Date beginDate, Date endDate) {
        LocalDate afterDate = LocalDate.of(getYear(beginDate), getMonth(beginDate), (int) getDayOfMounth(beginDate) + 1);
        LocalDate beforeDate = LocalDate.of(getYear(endDate), getMonth(endDate), (int) getDayOfMounth(endDate) + 1);
        return ChronoUnit.YEARS.between(afterDate, beforeDate);
    }

    /**
     * 获取指定时间是月的第几天
     */
    public static long getDayOfMounth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getYear(date), getMonth(date) - 1, 1);
        Date startTimeOfMounth = getDayStartTime(calendar.getTime());
        return getDiffDays(startTimeOfMounth, date);
    }

    /**
     * 获取指定日期是哪一月
     */
    public static int getMonth(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取指定时间的周开始时间
     */
    public static Date getBeginDayOfWeek(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            dayOfWeek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayOfWeek);
        return getDayStartTime(cal.getTime());
    }

    /**
     * 获取本年的开始时间
     */
    public static Date getBeginDayOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getYear(date));
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);
        return getDayStartTime(cal.getTime());
    }


    /**
     * 获取本月的开始时间
     */
    public static Date getBeginDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getYear(date), getMonth(date) - 1, 1);
        return getDayStartTime(calendar.getTime());
    }

    public static Date getEndDayOfMonth(Date date) {
        LocalDate date2 = date2LocalDate(date);
        Calendar calendar = Calendar.getInstance();
        calendar.set(date2.getYear(), date2.getMonthValue() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(date2.getYear(), date2.getMonthValue() - 1, day);
        return getDayEndTime(calendar.getTime());
    }


    /**
     * Date 转 localDate
     */
    public static LocalDate date2LocalDate(Date date) {
        Instant instant = date.toInstant();
        ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
        LocalDate localDate = zdt.toLocalDate();
        return localDate;
    }


    /**
     * 增加月
     */
    public static Date addMonth(Date sourceDate, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.MONTH, month);

        return c.getTime();
    }

    /**
     * 增加月
     */
    public static Date addDay(Date sourceDate, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.DAY_OF_MONTH, day);

        return c.getTime();
    }

    /**
     * 增加秒
     */
    public static Date addSecond(Date sourceDate, int second) {
        Calendar c = Calendar.getInstance();
        c.setTime(sourceDate);
        c.add(Calendar.SECOND, second);

        return c.getTime();
    }


    public static List<Date> findDates(Date beginTime, Date endTime) {
        List<Date> allDate = new ArrayList();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Date dBegin = beginTime;
            Date dEnd = endTime;
            allDate.add(dBegin);
            Calendar calBegin = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calBegin.setTime(dBegin);
            Calendar calEnd = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calEnd.setTime(dEnd);
            // 测试此日期是否在指定日期之后
            while (dEnd.after(calBegin.getTime())) {
                // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                allDate.add(calBegin.getTime());
            }
        } catch (Exception e) {

        }


        return allDate;
    }


}
